
from ctypes import *
from common_c import load_library

libnsa = load_library('libnsa')

class nsa_entry_t(Structure):
	_fields_ = (('name',  c_char_p),
	            ('offset', c_int32),
	            ('size', c_int32))
class nsa_entries_t(Structure):
	_fields_ = (('entry_number',  c_int),
	            ('entries', POINTER(nsa_entry_t)))

def read_nsa_indexes(path):
	if isinstance(path, unicode):
		import sys
		path = path.encode(sys.getfilesystemencoding())
	index = cast(libnsa.read_nsa_indexes(path), POINTER(nsa_entries_t))
	assert index
	return index

def free_nsa_indexes(indexes):
	libnsa.free_nsa_indexes(indexes)

def decode_entry(path, entry):
	if isinstance(path, unicode):
		import sys
		path = path.encode(sys.getfilesystemencoding())
	buffer = create_string_buffer(entry.original_size)
	n = libnsa.decode_nsa_entry_in_buffer(path, byref(entry), buffer, decrypter)
	if n:
		raise RuntimeError('decode_nsa_entry_in_buffer failed')
	return buffer.raw

from archive_base import Entry

class NSAEntry(Entry):
	def __init__(self, c_entry):
		self.name = unicode(c_entry.name) # XXX: non-ascii is not supported
		self.offset = c_entry.offset
		self.size = c_entry.size
	def decode(self):
		with open(self.path, 'rb') as stream:
			stream.seek(self.offset)
			return stream.read(self.size)

class NSAReader:
	def __init__(self, path):
		self.path = path
		indexes = read_nsa_indexes(path)
		try:
			contents = indexes.contents
			n = contents.entry_number
			entries = contents.entries
			self.entries = [NSAEntry(entries[i]) for i in xrange(n)]
		finally:
			free_nsa_indexes(indexes)


